home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / MISC3.C < prev    next >
C/C++ Source or Header  |  1992-12-07  |  59KB  |  2,557 lines

  1. /* source/misc3.c: misc code for maintaining the dungeon, printing player info
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #ifdef __TURBOC__
  10. #include    <stdio.h>
  11. #endif
  12.  
  13. #include "config.h"
  14. #include "constant.h"
  15. #include "types.h"
  16. #include "externs.h"
  17.  
  18. #include <ctype.h>
  19.  
  20. #ifndef USG
  21. #include <sys/types.h>
  22. #include <sys/param.h>
  23. #endif
  24.  
  25. #ifdef USG
  26. #ifndef ATARIST_MWC
  27. #include <string.h>
  28. #else
  29. char *index();
  30. #endif
  31. #else
  32. #include <strings.h>
  33. #endif
  34.  
  35. #if defined(LINT_ARGS)
  36. static void prt_lnum(char *, int32, int, int);
  37. static void prt_num(char *, int, int, int);
  38. static void prt_long(int32, int, int);
  39. static void prt_int(int, int, int);
  40. static void gain_level(void);
  41. #endif
  42.  
  43. static char *stat_names[] = { "STR : ", "INT : ", "WIS : ",
  44.                  "DEX : ", "CON : ", "CHR : " };
  45. #define BLANK_LENGTH    24
  46. static char blank_string[] = "                        ";
  47.  
  48.  
  49. /* Places a particular trap at location y, x        -RAK-    */
  50. void place_trap(y, x, subval)
  51. int y, x, subval;
  52. {
  53.   register int cur_pos;
  54.  
  55.   cur_pos = popt();
  56.   cave[y][x].tptr  = cur_pos;
  57.   invcopy(&t_list[cur_pos], OBJ_TRAP_LIST + subval);
  58. }
  59.  
  60.  
  61. /* Places rubble at location y, x            -RAK-    */
  62. void place_rubble(y, x)
  63. int y, x;
  64. {
  65.   register int cur_pos;
  66.   register cave_type *cave_ptr;
  67.  
  68.   cur_pos = popt();
  69.   cave_ptr = &cave[y][x];
  70.   cave_ptr->tptr = cur_pos;
  71.   cave_ptr->fval = BLOCKED_FLOOR;
  72.   invcopy(&t_list[cur_pos], OBJ_RUBBLE);
  73. }
  74.  
  75.  
  76. /* Places a treasure (Gold or Gems) at given row, column -RAK-    */
  77. void place_gold(y, x)
  78. int y, x;
  79. {
  80.   register int i, cur_pos;
  81. #ifdef M_XENIX
  82.   /* Avoid 'register' bug.  */
  83.   inven_type *t_ptr;
  84. #else
  85.   register inven_type *t_ptr;
  86. #endif
  87.  
  88.   cur_pos = popt();
  89.   i = ((randint(dun_level+2)+2) / 2) - 1;
  90.   if (randint(OBJ_GREAT) == 1)
  91.     i += randint(dun_level+1);
  92.   if (i >= MAX_GOLD)
  93.     i = MAX_GOLD - 1;
  94.   cave[y][x].tptr = cur_pos;
  95.   invcopy(&t_list[cur_pos], OBJ_GOLD_LIST+i);
  96.   t_ptr = &t_list[cur_pos];
  97.   t_ptr->cost += (8L * (long)randint((int)t_ptr->cost)) + randint(8);
  98.   if (cave[y][x].cptr == 1)
  99.     msg_print ("You feel something roll beneath your feet.");
  100. }
  101.  
  102.  
  103. /* Returns the array number of a random object        -RAK-    */
  104. int get_obj_num(level)
  105. int level;
  106. {
  107.   register int i, j;
  108.  
  109.   if (level == 0)
  110.     i = randint(t_level[0]) - 1;
  111.   else
  112.     {
  113.       if (level >= MAX_OBJ_LEVEL)
  114.     level = MAX_OBJ_LEVEL;
  115.       else if (randint(OBJ_GREAT) == 1)
  116.     {
  117.       level = level * MAX_OBJ_LEVEL / randint (MAX_OBJ_LEVEL) + 1;
  118.       if (level > MAX_OBJ_LEVEL)
  119.         level = MAX_OBJ_LEVEL;
  120.     }
  121.  
  122.       /* This code has been added to make it slightly more likely to get the
  123.      higher level objects.    Originally a uniform distribution over all
  124.      objects less than or equal to the dungeon level.  This distribution
  125.      makes a level n objects occur approx 2/n% of the time on level n,
  126.      and 1/2n are 0th level. */
  127.  
  128.       if (randint(2) == 1)
  129.     i = randint(t_level[level]) - 1;
  130.       else /* Choose three objects, pick the highest level. */
  131.     {
  132.       i = randint(t_level[level]) - 1;
  133.       j = randint(t_level[level]) - 1;
  134.       if (i < j)
  135.         i = j;
  136.       j = randint(t_level[level]) - 1;
  137.       if (i < j)
  138.         i = j;
  139.       j = object_list[sorted_objects[i]].level;
  140.       if (j == 0)
  141.         i = randint(t_level[0]) - 1;
  142.       else
  143.         i = randint(t_level[j]-t_level[j-1]) - 1 + t_level[j-1];
  144.     }
  145.     }
  146.   return(i);
  147. }
  148.  
  149.  
  150. /* Places an object at given row, column co-ordinate    -RAK-    */
  151. void place_object(y, x)
  152. int y, x;
  153. {
  154.   register int cur_pos, tmp;
  155.  
  156.   cur_pos = popt();
  157.   cave[y][x].tptr = cur_pos;
  158.   /* split this line up to avoid a reported compiler bug */
  159.   tmp = get_obj_num(dun_level);
  160.   invcopy(&t_list[cur_pos], sorted_objects[tmp]);
  161.   magic_treasure(cur_pos, dun_level);
  162.   if (cave[y][x].cptr == 1)
  163.     msg_print ("You feel something roll beneath your feet.");    /* -CJS- */
  164. }
  165.  
  166.  
  167. /* Allocates an object for tunnels and rooms        -RAK-    */
  168. void alloc_object(alloc_set, typ, num)
  169. int (*alloc_set)();
  170. int typ, num;
  171. {
  172.   register int i, j, k;
  173.  
  174.   for (k = 0; k < num; k++)
  175.     {
  176.       do
  177.     {
  178.       i = randint(cur_height) - 1;
  179.       j = randint(cur_width) - 1;
  180.     }
  181.       /* don't put an object beneath the player, this could cause problems
  182.      if player is standing under rubble, or on a trap */
  183.       while ((!(*alloc_set)(cave[i][j].fval)) ||
  184.          (cave[i][j].tptr != 0) || (i == char_row && j == char_col));
  185.       if (typ < 4) {    /* typ == 2 not used, used to be visible traps */
  186.     if (typ == 1) place_trap(i, j, randint(MAX_TRAP)-1); /* typ == 1 */
  187.     else          place_rubble(i, j); /* typ == 3 */
  188.       } else {
  189.     if (typ == 4) place_gold(i, j); /* typ == 4 */
  190.     else          place_object(i, j); /* typ == 5 */
  191.       }
  192.     }
  193. }
  194.  
  195.  
  196. /* Creates objects nearby the coordinates given        -RAK-    */
  197. void random_object(y, x, num)
  198. int y, x, num;
  199. {
  200.   register int i, j, k;
  201.   register cave_type *cave_ptr;
  202.  
  203.   do
  204.     {
  205.       i = 0;
  206.       do
  207.     {
  208.       j = y - 3 + randint(5);
  209.       k = x - 4 + randint(7);
  210.       cave_ptr = &cave[j][k];
  211.       if (in_bounds(j, k) && (cave_ptr->fval <= MAX_CAVE_FLOOR)
  212.           && (cave_ptr->tptr == 0))
  213.         {
  214.           if (randint(100) < 75)
  215.         place_object(j, k);
  216.           else
  217.         place_gold(j, k);
  218.           i = 9;
  219.         }
  220.       i++;
  221.     }
  222.       while(i <= 10);
  223.       num--;
  224.     }
  225.   while (num != 0);
  226. }
  227.  
  228.  
  229. /* Converts stat num into string            -RAK-    */
  230. void cnv_stat(stat, out_val)
  231. int8u stat;
  232. char *out_val;
  233. {
  234.   register int part1, part2;
  235.  
  236.   if (stat > 18)
  237.     {
  238.       part1 = 18;
  239.       part2 = stat - 18;
  240.       if (part2 == 100)
  241.     (void) strcpy(out_val, "18/100");
  242.       else
  243.     (void) sprintf(out_val, " %2d/%02d", part1, part2);
  244.     }
  245.   else
  246.     (void) sprintf(out_val, "%6d", stat);
  247. }
  248.  
  249.  
  250. /* Print character stat in given row, column        -RAK-    */
  251. void prt_stat(stat)
  252. int stat;
  253. {
  254.   stat_type out_val1;
  255.  
  256.   cnv_stat(py.stats.use_stat[stat], out_val1);
  257.   put_buffer(stat_names[stat], 6+stat, STAT_COLUMN);
  258.   put_buffer (out_val1, 6+stat, STAT_COLUMN+6);
  259. }
  260.  
  261.  
  262. /* Print character info in given row, column        -RAK-    */
  263. /* the longest title is 13 characters, so only pad to 13 */
  264. void prt_field(info, row, column)
  265. char *info;
  266. int row, column;
  267. {
  268.   put_buffer (&blank_string[BLANK_LENGTH-13], row, column);
  269.   put_buffer (info, row, column);
  270. }
  271.  
  272. /* Print long number with header at given row, column */
  273. static void prt_lnum(header, num, row, column)
  274. char *header;
  275. int32 num;
  276. int row, column;
  277. {
  278.   vtype out_val;
  279.  
  280.   (void) sprintf(out_val, "%s: %6ld", header, num);
  281.   put_buffer(out_val, row, column);
  282. }
  283.  
  284. /* Print number with header at given row, column    -RAK-    */
  285. static void prt_num(header, num, row, column)
  286. char *header;
  287. int num, row, column;
  288. {
  289.   vtype out_val;
  290.  
  291.   (void) sprintf(out_val, "%s: %6d", header, num);
  292.   put_buffer(out_val, row, column);
  293. }
  294.  
  295. /* Print long number at given row, column */
  296. static void prt_long(num, row, column)
  297. int32 num;
  298. int row, column;
  299. {
  300.   vtype out_val;
  301.  
  302.   (void) sprintf(out_val, "%6ld", num);
  303.   put_buffer(out_val, row, column);
  304. }
  305.  
  306. /* Print number at given row, column    -RAK-    */
  307. static void prt_int(num, row, column)
  308. int num, row, column;
  309. {
  310.   vtype out_val;
  311.  
  312.   (void) sprintf(out_val, "%6d", num);
  313.   put_buffer(out_val, row, column);
  314. }
  315.  
  316.  
  317. /* Adjustment for wisdom/intelligence                -JWT-    */
  318. int stat_adj(stat)
  319. int stat;
  320. {
  321.   register int value;
  322.  
  323.   value = py.stats.use_stat[stat];
  324.   if (value > 117)
  325.     return(7);
  326.   else if (value > 107)
  327.     return(6);
  328.   else if (value > 87)
  329.     return(5);
  330.   else if (value > 67)
  331.     return(4);
  332.   else if (value > 17)
  333.     return(3);
  334.   else if (value > 14)
  335.     return(2);
  336.   else if (value > 7)
  337.     return(1);
  338.   else
  339.     return(0);
  340. }
  341.  
  342.  
  343. /* Adjustment for charisma                -RAK-    */
  344. /* Percent decrease or increase in price of goods         */
  345. int chr_adj()
  346. {
  347.   register int charisma;
  348.  
  349.   charisma = py.stats.use_stat[A_CHR];
  350.   if (charisma > 117)
  351.     return(90);
  352.   else if (charisma > 107)
  353.     return(92);
  354.   else if (charisma > 87)
  355.     return(94);
  356.   else if (charisma > 67)
  357.     return(96);
  358.   else if (charisma > 18)
  359.     return(98);
  360.   else
  361.     switch(charisma)
  362.       {
  363.       case 18:    return(100);
  364.       case 17:    return(101);
  365.       case 16:    return(102);
  366.       case 15:    return(103);
  367.       case 14:    return(104);
  368.       case 13:    return(106);
  369.       case 12:    return(108);
  370.       case 11:    return(110);
  371.       case 10:    return(112);
  372.       case 9:  return(114);
  373.       case 8:  return(116);
  374.       case 7:  return(118);
  375.       case 6:  return(120);
  376.       case 5:  return(122);
  377.       case 4:  return(125);
  378.       case 3:  return(130);
  379.       default: return(100);
  380.       }
  381. }
  382.  
  383.  
  384. /* Returns a character's adjustment to hit points     -JWT-     */
  385. int con_adj()
  386. {
  387.   register int con;
  388.  
  389.   con = py.stats.use_stat[A_CON];
  390.   if (con < 7)
  391.     return(con - 7);
  392.   else if (con < 17)
  393.     return(0);
  394.   else if (con ==  17)
  395.     return(1);
  396.   else if (con <  94)
  397.     return(2);
  398.   else if (con < 117)
  399.     return(3);
  400.   else
  401.     return(4);
  402. }
  403.  
  404.  
  405. char *title_string()
  406. {
  407.   register char *p;
  408.  
  409.   if (py.misc.lev < 1)
  410.     p = "Babe in arms";
  411.   else if (py.misc.lev <= MAX_PLAYER_LEVEL)
  412.     p = player_title[py.misc.pclass][py.misc.lev-1];
  413.   else if (py.misc.male)
  414.     p = "**KING**";
  415.   else
  416.     p = "**QUEEN**";
  417.   return p;
  418. }
  419.  
  420.  
  421. /* Prints title of character                -RAK-    */
  422. void prt_title()
  423. {
  424.   prt_field(title_string(), 4, STAT_COLUMN);
  425. }
  426.  
  427.  
  428. /* Prints level                        -RAK-    */
  429. void prt_level()
  430. {
  431.   prt_int((int)py.misc.lev, 13, STAT_COLUMN+6);
  432. }
  433.  
  434.  
  435. /* Prints players current mana points.         -RAK-    */
  436. void prt_cmana()
  437. {
  438.   prt_int(py.misc.cmana, 15, STAT_COLUMN+6);
  439. }
  440.  
  441.  
  442. /* Prints Max hit points                -RAK-    */
  443. void prt_mhp()
  444. {
  445.   prt_int(py.misc.mhp, 16, STAT_COLUMN+6);
  446. }
  447.  
  448.  
  449. /* Prints players current hit points            -RAK-    */
  450. void prt_chp()
  451. {
  452.   prt_int(py.misc.chp, 17, STAT_COLUMN+6);
  453. }
  454.  
  455.  
  456. /* prints current AC                    -RAK-    */
  457. void prt_pac()
  458. {
  459.   prt_int(py.misc.dis_ac, 19, STAT_COLUMN+6);
  460. }
  461.  
  462.  
  463. /* Prints current gold                    -RAK-    */
  464. void prt_gold()
  465. {
  466.   prt_long(py.misc.au, 20, STAT_COLUMN+6);
  467. }
  468.  
  469.  
  470. /* Prints depth in stat area                -RAK-    */
  471. void prt_depth()
  472. {
  473.   vtype depths;
  474.   register int depth;
  475.  
  476.   depth = dun_level*50;
  477.   if (depth == 0)
  478.     (void) strcpy(depths, "Town level");
  479.   else
  480.     (void) sprintf(depths, "%d feet", depth);
  481.   prt(depths, 23, 65);
  482. }
  483.  
  484.  
  485. /* Prints status of hunger                -RAK-    */
  486. void prt_hunger()
  487. {
  488.   if (PY_WEAK & py.flags.status)
  489.     put_buffer("Weak  ", 23, 0);
  490.   else if (PY_HUNGRY & py.flags.status)
  491.     put_buffer("Hungry", 23, 0);
  492.   else
  493.     put_buffer(&blank_string[BLANK_LENGTH-6], 23, 0);
  494. }
  495.  
  496.  
  497. /* Prints Blind status                    -RAK-    */
  498. void prt_blind()
  499. {
  500.   if (PY_BLIND & py.flags.status)
  501.     put_buffer("Blind", 23, 7);
  502.   else
  503.     put_buffer(&blank_string[BLANK_LENGTH-5], 23, 7);
  504. }
  505.  
  506.  
  507. /* Prints Confusion status                -RAK-    */
  508. void prt_confused()
  509. {
  510.   if (PY_CONFUSED & py.flags.status)
  511.     put_buffer("Confused", 23, 13);
  512.   else
  513.     put_buffer(&blank_string[BLANK_LENGTH-8], 23, 13);
  514. }
  515.  
  516.  
  517. /* Prints Fear status                    -RAK-    */
  518. void prt_afraid()
  519. {
  520.   if (PY_FEAR & py.flags.status)
  521.     put_buffer("Afraid", 23, 22);
  522.   else
  523.     put_buffer(&blank_string[BLANK_LENGTH-6], 23, 22);
  524. }
  525.  
  526.  
  527. /* Prints Poisoned status                -RAK-    */
  528. void prt_poisoned()
  529. {
  530.   if (PY_POISONED & py.flags.status)
  531.     put_buffer("Poisoned", 23, 29);
  532.   else
  533.     put_buffer(&blank_string[BLANK_LENGTH-8], 23, 29);
  534. }
  535.  
  536.  
  537. /* Prints Searching, Resting, Paralysis, or 'count' status    -RAK-    */
  538. void prt_state()
  539. {
  540.   char tmp[16];
  541. #ifdef ATARIST_MWC
  542.   int32u holder;
  543. #endif
  544.  
  545. #ifdef ATARIST_MWC
  546.   py.flags.status &= ~(holder = PY_REPEAT);
  547. #else
  548.   py.flags.status &= ~PY_REPEAT;
  549. #endif
  550.   if (py.flags.paralysis > 1)
  551.     put_buffer ("Paralysed", 23, 38);
  552.   else if (PY_REST & py.flags.status)
  553.     {
  554.       if (py.flags.rest < 0)
  555.     (void) strcpy (tmp, "Rest *");
  556.       else if (display_counts)
  557.     (void) sprintf (tmp, "Rest %-5d", py.flags.rest);
  558.       else
  559.     (void) strcpy (tmp, "Rest");
  560.       put_buffer (tmp, 23, 38);
  561.     }
  562.   else if (command_count > 0)
  563.     {
  564.       if (display_counts)
  565.     (void) sprintf (tmp, "Repeat %-3d", command_count);
  566.       else
  567.     (void) strcpy (tmp, "Repeat");
  568. #ifdef ATARIST_MWC
  569.       py.flags.status |= holder;
  570. #else
  571.       py.flags.status |= PY_REPEAT;
  572. #endif
  573.       put_buffer (tmp, 23, 38);
  574.       if (PY_SEARCH & py.flags.status)
  575.     put_buffer ("Search", 23, 38);
  576.     }
  577.   else if (PY_SEARCH & py.flags.status)
  578.     put_buffer("Searching", 23, 38);
  579.   else        /* "repeat 999" is 10 characters */
  580.     put_buffer(&blank_string[BLANK_LENGTH-10], 23, 38);
  581. }
  582.  
  583.  
  584. /* Prints the speed of a character.            -CJS- */
  585. void prt_speed ()
  586. {
  587.   register int i;
  588.  
  589.   i = py.flags.speed;
  590.   if (PY_SEARCH & py.flags.status)   /* Search mode. */
  591.     i--;
  592.   if (i > 1)
  593.     put_buffer ("Very Slow", 23, 49);
  594.   else if (i == 1)
  595.     put_buffer ("Slow     ", 23, 49);
  596.   else if (i == 0)
  597.     put_buffer (&blank_string[BLANK_LENGTH-9], 23, 49);
  598.   else if (i == -1)
  599.     put_buffer ("Fast     ", 23, 49);
  600.   else
  601.     put_buffer ("Very Fast", 23, 49);
  602. }
  603.  
  604.  
  605. void prt_study()
  606. {
  607. #ifdef ATARIST_MWC
  608.   int32u holder;
  609. #endif
  610.  
  611. #ifdef ATARIST_MWC
  612.   py.flags.status &= ~(holder = PY_STUDY);
  613. #else
  614.   py.flags.status &= ~PY_STUDY;
  615. #endif
  616.   if (py.flags.new_spells == 0)
  617.     put_buffer (&blank_string[BLANK_LENGTH-5], 23, 59);
  618.   else
  619.     put_buffer ("Study", 23, 59);
  620. }
  621.  
  622.  
  623. /* Prints winner status on display            -RAK-    */
  624. void prt_winner()
  625. {
  626.   if (noscore & 0x2)
  627.     {
  628.       if (wizard)
  629.     put_buffer("Is wizard  ", 22, 0);
  630.       else
  631.     put_buffer("Was wizard ", 22, 0);
  632.     }
  633.   else if (noscore & 0x1)
  634.     put_buffer("Resurrected", 22, 0);
  635.   else if (noscore & 0x4)
  636.     put_buffer ("Duplicate", 22, 0);
  637.   else if (total_winner)
  638.     put_buffer("*Winner*   ", 22, 0);
  639. }
  640.  
  641.  
  642. int8u modify_stat (stat, amount)
  643. int stat;
  644. int16 amount;
  645. {
  646.   register int loop, i;
  647.   register int8u tmp_stat;
  648.  
  649.   tmp_stat = py.stats.cur_stat[stat];
  650.   loop = (amount < 0 ? -amount : amount);
  651.   for (i = 0; i < loop; i++)
  652.     {
  653.       if (amount > 0)
  654.     {
  655.       if (tmp_stat < 18)
  656.         tmp_stat++;
  657.       else if (tmp_stat < 108)
  658.         tmp_stat += 10;
  659.       else
  660.         tmp_stat = 118;
  661.     }
  662.       else
  663.     {
  664.       if (tmp_stat > 27)
  665.         tmp_stat -= 10;
  666.       else if (tmp_stat > 18)
  667.         tmp_stat = 18;
  668.       else if (tmp_stat > 3)
  669.         tmp_stat--;
  670.     }
  671.     }
  672.   return tmp_stat;
  673. }
  674.  
  675.  
  676. /* Set the value of the stat which is actually used.     -CJS- */
  677. void set_use_stat(stat)
  678. int stat;
  679. {
  680. #ifdef ATARIST_MWC
  681.   int32u holder;
  682. #endif
  683.  
  684.   py.stats.use_stat[stat] = modify_stat (stat, py.stats.mod_stat[stat]);
  685.  
  686.   if (stat == A_STR)
  687.     {
  688. #ifdef ATARIST_MWC
  689.       py.flags.status |= (holder = PY_STR_WGT);
  690. #else
  691.       py.flags.status |= PY_STR_WGT;
  692. #endif
  693.       calc_bonuses();
  694.     }
  695.   else if (stat == A_DEX)
  696.     calc_bonuses();
  697.   else if (stat == A_INT && class[py.misc.pclass].spell == MAGE)
  698.     {
  699.       calc_spells(A_INT);
  700.       calc_mana(A_INT);
  701.     }
  702.   else if (stat == A_WIS && class[py.misc.pclass].spell == PRIEST)
  703.     {
  704.       calc_spells(A_WIS);
  705.       calc_mana(A_WIS);
  706.     }
  707.   else if (stat == A_CON)
  708.     calc_hitpoints();
  709. }
  710.  
  711.  
  712. /* Increases a stat by one randomized level        -RAK-    */
  713. int inc_stat(stat)
  714. register int stat;
  715. {
  716.   register int tmp_stat, gain;
  717.  
  718.   tmp_stat = py.stats.cur_stat[stat];
  719.   if (tmp_stat < 118)
  720.     {
  721.       if (tmp_stat < 18)
  722.     tmp_stat++;
  723.       else if (tmp_stat < 116)
  724.     {
  725.       /* stat increases by 1/6 to 1/3 of difference from max */
  726.       gain = ((118 - tmp_stat)/3 + 1) >> 1;
  727.       tmp_stat += randint(gain) + gain;
  728.     }
  729.       else
  730.     tmp_stat++;
  731.  
  732.       py.stats.cur_stat[stat] = tmp_stat;
  733.       if (tmp_stat > py.stats.max_stat[stat])
  734.     py.stats.max_stat[stat] = tmp_stat;
  735.       set_use_stat (stat);
  736.       prt_stat (stat);
  737.       return TRUE;
  738.     }
  739.   else
  740.     return FALSE;
  741. }
  742.  
  743.  
  744. /* Decreases a stat by one randomized level        -RAK-    */
  745. int dec_stat(stat)
  746. register int stat;
  747. {
  748.   register int tmp_stat, loss;
  749.  
  750.   tmp_stat = py.stats.cur_stat[stat];
  751.   if (tmp_stat > 3)
  752.     {
  753.       if (tmp_stat < 19)
  754.     tmp_stat--;
  755.       else if (tmp_stat < 117)
  756.     {
  757.       loss = (((118 - tmp_stat) >> 1) + 1) >> 1;
  758.       tmp_stat += -randint(loss) - loss;
  759.       if (tmp_stat < 18)
  760.         tmp_stat = 18;
  761.     }
  762.       else
  763.     tmp_stat--;
  764.  
  765.       py.stats.cur_stat[stat] = tmp_stat;
  766.       set_use_stat (stat);
  767.       prt_stat (stat);
  768.       return TRUE;
  769.     }
  770.   else
  771.     return FALSE;
  772. }
  773.  
  774.  
  775. /* Restore a stat.  Return TRUE only if this actually makes a difference. */
  776. int res_stat (stat)
  777. int stat;
  778. {
  779.   register int i;
  780.  
  781.   i = py.stats.max_stat[stat] - py.stats.cur_stat[stat];
  782.   if (i)
  783.     {
  784.       py.stats.cur_stat[stat] += i;
  785.       set_use_stat (stat);
  786.       prt_stat (stat);
  787.       return TRUE;
  788.     }
  789.   return FALSE;
  790. }
  791.  
  792. /* Boost a stat artificially (by wearing something). If the display argument
  793.    is TRUE, then increase is shown on the screen. */
  794. void bst_stat (stat, amount)
  795. int stat, amount;
  796. {
  797. #ifdef ATARIST_MWC
  798.   int32u holder;
  799. #endif
  800.  
  801.   py.stats.mod_stat[stat] += amount;
  802.  
  803.   set_use_stat (stat);
  804.   /* can not call prt_stat() here, may be in store, may be in inven_command */
  805. #ifdef ATARIST_MWC
  806.   py.flags.status |= ((holder = PY_STR) << stat);
  807. #else
  808.   py.flags.status |= (PY_STR << stat);
  809. #endif
  810. }
  811.  
  812.  
  813. /* Returns a character's adjustment to hit.         -JWT-     */
  814. int tohit_adj()
  815. {
  816.   register int total, stat;
  817.  
  818.   stat = py.stats.use_stat[A_DEX];
  819.   if      (stat <   4)    total = -3;
  820.   else if (stat <   6)    total = -2;
  821.   else if (stat <   8)    total = -1;
  822.   else if (stat <  16)    total =     0;
  823.   else if (stat <  17)    total =     1;
  824.   else if (stat <  18)    total =     2;
  825.   else if (stat <  69)    total =     3;
  826.   else if (stat < 118)    total =     4;
  827.   else            total =     5;
  828.   stat = py.stats.use_stat[A_STR];
  829.   if      (stat <   4)    total -= 3;
  830.   else if (stat <   5)    total -= 2;
  831.   else if (stat <   7)    total -= 1;
  832.   else if (stat <  18)    total -= 0;
  833.   else if (stat <  94)    total += 1;
  834.   else if (stat < 109)    total += 2;
  835.   else if (stat < 117)    total += 3;
  836.   else            total += 4;
  837.   return(total);
  838. }
  839.  
  840.  
  841. /* Returns a character's adjustment to armor class     -JWT-     */
  842. int toac_adj()
  843. {
  844.   register int stat;
  845.  
  846.   stat = py.stats.use_stat[A_DEX];
  847.   if      (stat <   4)    return(-4);
  848.   else if (stat ==  4)    return(-3);
  849.   else if (stat ==  5)    return(-2);
  850.   else if (stat ==  6)    return(-1);
  851.   else if (stat <  15)    return( 0);
  852.   else if (stat <  18)    return( 1);
  853.   else if (stat <  59)    return( 2);
  854.   else if (stat <  94)    return( 3);
  855.   else if (stat < 117)    return( 4);
  856.   else            return( 5);
  857. }
  858.  
  859.  
  860. /* Returns a character's adjustment to disarm         -RAK-     */
  861. int todis_adj()
  862. {
  863.   register int stat;
  864.  
  865.   stat = py.stats.use_stat[A_DEX];
  866.   if      (stat <   3)    return(-8);
  867.   else if (stat ==  4)    return(-6);
  868.   else if (stat ==  5)    return(-4);
  869.   else if (stat ==  6)    return(-2);
  870.   else if (stat ==  7)    return(-1);
  871.   else if (stat <  13)    return( 0);
  872.   else if (stat <  16)    return( 1);
  873.   else if (stat <  18)    return( 2);
  874.   else if (stat <  59)    return( 4);
  875.   else if (stat <  94)    return( 5);
  876.   else if (stat < 117)    return( 6);
  877.   else            return( 8);
  878. }
  879.  
  880.  
  881. /* Returns a character's adjustment to damage         -JWT-     */
  882. int todam_adj()
  883. {
  884.   register int stat;
  885.  
  886.   stat = py.stats.use_stat[A_STR];
  887.   if      (stat <   4)    return(-2);
  888.   else if (stat <   5)    return(-1);
  889.   else if (stat <  16)    return( 0);
  890.   else if (stat <  17)    return( 1);
  891.   else if (stat <  18)    return( 2);
  892.   else if (stat <  94)    return( 3);
  893.   else if (stat < 109)    return( 4);
  894.   else if (stat < 117)    return( 5);
  895.   else            return( 6);
  896. }
  897.  
  898.  
  899. /* Prints character-screen info                -RAK-    */
  900. void prt_stat_block()
  901. {
  902.   register int32u status;
  903.   register struct misc *m_ptr;
  904.   register int i;
  905.  
  906.   m_ptr = &py.misc;
  907.   prt_field(race[py.misc.prace].trace,      2, STAT_COLUMN);
  908.   prt_field(class[py.misc.pclass].title,  3, STAT_COLUMN);
  909.   prt_field(title_string(),          4, STAT_COLUMN);
  910.   for (i = 0; i < 6; i++)
  911.     prt_stat (i);
  912.   prt_num ("LEV ", (int)m_ptr->lev,    13, STAT_COLUMN);
  913.   prt_lnum("EXP ", m_ptr->exp,           14, STAT_COLUMN);
  914.   prt_num ("MANA", m_ptr->cmana,     15, STAT_COLUMN);
  915.   prt_num ("MHP ", m_ptr->mhp,           16, STAT_COLUMN);
  916.   prt_num ("CHP ", m_ptr->chp,     17, STAT_COLUMN);
  917.   prt_num ("AC  ", m_ptr->dis_ac,      19, STAT_COLUMN);
  918.   prt_lnum("GOLD", m_ptr->au,           20, STAT_COLUMN);
  919.   prt_winner();
  920.   status = py.flags.status;
  921.   if ((PY_HUNGRY|PY_WEAK) & status)
  922.     prt_hunger();
  923.   if (PY_BLIND & status)
  924.     prt_blind();
  925.   if (PY_CONFUSED & status)
  926.     prt_confused();
  927.   if (PY_FEAR & status)
  928.     prt_afraid();
  929.   if (PY_POISONED & status)
  930.     prt_poisoned();
  931.   if ((PY_SEARCH|PY_REST) & status)
  932.     prt_state ();
  933.   /* if speed non zero, print it, modify speed if Searching */
  934.   if (py.flags.speed - ((PY_SEARCH & status) >> 8) != 0)
  935.     prt_speed ();
  936.   /* display the study field */
  937.   prt_study();
  938. }
  939.  
  940.  
  941. /* Draws entire screen                    -RAK-    */
  942. void draw_cave()
  943. {
  944.   clear_screen ();
  945.   prt_stat_block();
  946.   prt_map();
  947.   prt_depth();
  948. }
  949.  
  950.  
  951. /* Prints the following information on the screen.    -JWT-    */
  952. void put_character()
  953. {
  954.   register struct misc *m_ptr;
  955.  
  956.   m_ptr = &py.misc;
  957.   clear_screen ();
  958.   put_buffer ("Name        :", 2, 1);
  959.   put_buffer ("Race        :", 3, 1);
  960.   put_buffer ("Sex         :", 4, 1);
  961.   put_buffer ("Class       :", 5, 1);
  962.   if (character_generated)
  963.     {
  964.       put_buffer (m_ptr->name, 2, 15);
  965.       put_buffer (race[m_ptr->prace].trace, 3, 15);
  966.       put_buffer ((m_ptr->male ? "Male" : "Female"), 4, 15);
  967.       put_buffer (class[m_ptr->pclass].title, 5, 15);
  968.     }
  969. }
  970.  
  971.  
  972. /* Prints the following information on the screen.    -JWT-    */
  973. void put_stats()
  974. {
  975.   register struct misc *m_ptr;
  976.   register int i;
  977.   vtype buf;
  978.  
  979.   m_ptr = &py.misc;
  980.   for (i = 0; i < 6; i++)
  981.     {
  982.       cnv_stat (py.stats.use_stat[i], buf);
  983.       put_buffer (stat_names[i], 2+i, 61);
  984.       put_buffer (buf, 2+i, 66);
  985.       if (py.stats.max_stat[i] > py.stats.cur_stat[i])
  986.     {
  987.       cnv_stat (py.stats.max_stat[i], buf);
  988.       put_buffer (buf, 2+i, 73);
  989.     }
  990.     }
  991.   prt_num("+ To Hit    ", m_ptr->dis_th,  9, 1);
  992.   prt_num("+ To Damage ", m_ptr->dis_td, 10, 1);
  993.   prt_num("+ To AC     ", m_ptr->dis_tac, 11, 1);
  994.   prt_num("  Total AC  ", m_ptr->dis_ac, 12, 1);
  995. }
  996.  
  997.  
  998. /* Returns a rating of x depending on y            -JWT-    */
  999. char *likert(x, y)
  1000. int x, y;
  1001. {
  1002.   switch((x/y))
  1003.     {
  1004.       case -3: case -2: case -1: return("Very Bad");
  1005.       case 0: case 1:         return("Bad");
  1006.       case 2:             return("Poor");
  1007.       case 3: case 4:         return("Fair");
  1008.       case  5:             return("Good");
  1009.       case 6:             return("Very Good");
  1010.       case 7: case 8:         return("Excellent");
  1011.       default:             return("Superb");
  1012.       }
  1013. }
  1014.  
  1015.  
  1016. /* Prints age, height, weight, and SC            -JWT-    */
  1017. void put_misc1()
  1018. {
  1019.   register struct misc *m_ptr;
  1020.  
  1021.   m_ptr = &py.misc;
  1022.   prt_num("Age          ", (int)m_ptr->age, 2, 38);
  1023.   prt_num("Height       ", (int)m_ptr->ht, 3, 38);
  1024.   prt_num("Weight       ", (int)m_ptr->wt, 4, 38);
  1025.   prt_num("Social Class ", (int)m_ptr->sc, 5, 38);
  1026. }
  1027.  
  1028.  
  1029. /* Prints the following information on the screen.    -JWT-    */
  1030. void put_misc2()
  1031. {
  1032.   register struct misc *m_ptr;
  1033.  
  1034.   m_ptr = &py.misc;
  1035.   prt_num("Level      ", (int)m_ptr->lev, 9, 29);
  1036.   prt_lnum("Experience ", m_ptr->exp, 10, 29);
  1037.   prt_lnum("Max Exp    ", m_ptr->max_exp, 11, 29);
  1038.   if (m_ptr->lev == MAX_PLAYER_LEVEL)
  1039.     prt ("Exp to Adv.: ******", 12, 29);
  1040.   else
  1041.     prt_lnum("Exp to Adv.", (int32)(player_exp[m_ptr->lev-1]
  1042.                     * m_ptr->expfact / 100), 12, 29);
  1043.   prt_lnum("Gold       ", m_ptr->au, 13, 29);
  1044.   prt_num("Max Hit Points ", m_ptr->mhp, 9, 52);
  1045.   prt_num("Cur Hit Points ", m_ptr->chp, 10, 52);
  1046.   prt_num("Max Mana       ", m_ptr->mana, 11, 52);
  1047.   prt_num("Cur Mana       ", m_ptr->cmana, 12, 52);
  1048. }
  1049.  
  1050.  
  1051. /* Prints ratings on certain abilities            -RAK-    */
  1052. void put_misc3()
  1053. {
  1054.   int xbth, xbthb, xfos, xsrh, xstl, xdis, xsave, xdev;
  1055.   vtype xinfra;
  1056.   register struct misc *p_ptr;
  1057.  
  1058.   clear_from(14);
  1059.   p_ptr = &py.misc;
  1060.   xbth    = p_ptr->bth + p_ptr->ptohit*BTH_PLUS_ADJ
  1061.     + (class_level_adj[p_ptr->pclass][CLA_BTH] * p_ptr->lev);
  1062.   xbthb = p_ptr->bthb + p_ptr->ptohit*BTH_PLUS_ADJ
  1063.     + (class_level_adj[p_ptr->pclass][CLA_BTHB] * p_ptr->lev);
  1064.   /* this results in a range from 0 to 29 */
  1065.   xfos    = 40 - p_ptr->fos;
  1066.   if (xfos < 0)     xfos = 0;
  1067.   xsrh    = p_ptr->srh;
  1068.   /* this results in a range from 0 to 9 */
  1069.   xstl    = p_ptr->stl + 1;
  1070.   xdis    = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
  1071.     + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
  1072.   xsave = p_ptr->save + stat_adj(A_WIS)
  1073.     + (class_level_adj[p_ptr->pclass][CLA_SAVE] * p_ptr->lev / 3);
  1074.   xdev    = p_ptr->save + stat_adj(A_INT)
  1075.     + (class_level_adj[p_ptr->pclass][CLA_DEVICE] * p_ptr->lev / 3);
  1076.  
  1077.   (void) sprintf(xinfra, "%d feet", py.flags.see_infra*10);
  1078.  
  1079.   put_buffer ("(Miscellaneous Abilities)", 15, 25);
  1080.   put_buffer ("Fighting    :", 16, 1);
  1081.   put_buffer (likert (xbth, 12), 16, 15);
  1082.   put_buffer ("Bows/Throw  :", 17, 1);
  1083.   put_buffer (likert (xbthb, 12), 17, 15);
  1084.   put_buffer ("Saving Throw:", 18, 1);
  1085.   put_buffer (likert (xsave, 6), 18, 15);
  1086.  
  1087.   put_buffer ("Stealth     :", 16, 28);
  1088.   put_buffer (likert (xstl, 1), 16, 42);
  1089.   put_buffer ("Disarming   :", 17, 28);
  1090.   put_buffer (likert (xdis, 8), 17, 42);
  1091.   put_buffer ("Magic Device:", 18, 28);
  1092.   put_buffer (likert (xdev, 6), 18, 42);
  1093.  
  1094.   put_buffer ("Perception  :", 16, 55);
  1095.   put_buffer (likert (xfos, 3), 16, 69);
  1096.   put_buffer ("Searching   :", 17, 55);
  1097.   put_buffer (likert (xsrh, 6), 17, 69);
  1098.   put_buffer ("Infra-Vision:", 18, 55);
  1099.   put_buffer (xinfra, 18, 69);
  1100. }
  1101.  
  1102.  
  1103. /* Used to display the character on the screen.        -RAK-    */
  1104. void display_char()
  1105. {
  1106.   put_character();
  1107.   put_misc1();
  1108.   put_stats();
  1109.   put_misc2();
  1110.   put_misc3();
  1111. }
  1112.  
  1113.  
  1114. /* Gets a name for the character            -JWT-    */
  1115. void get_name()
  1116. {
  1117.   prt("Enter your player's name  [press <RETURN> when finished]", 21, 2);
  1118.   put_buffer (&blank_string[BLANK_LENGTH-23], 2, 15);
  1119. #if defined(MAC) || defined(AMIGA)
  1120.   /* Force player to give a name, would be nice to get name from chooser
  1121.      (STR -16096), but that name might be too long */
  1122.   while (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0);
  1123. #else
  1124.   if (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0)
  1125.     {
  1126.       user_name (py.misc.name);
  1127.       put_buffer (py.misc.name, 2, 15);
  1128.     }
  1129. #endif
  1130.   clear_from (20);
  1131. #ifdef MAC
  1132.   /* Use the new name to set save file default name. */
  1133.   initsavedefaults();
  1134. #endif
  1135. }
  1136.  
  1137.  
  1138. /* Changes the name of the character            -JWT-    */
  1139. void change_name()
  1140. {
  1141.   register char c;
  1142.   register int flag;
  1143. #ifndef MAC
  1144.   vtype temp;
  1145. #endif
  1146.  
  1147.   flag = FALSE;
  1148.   display_char();
  1149.   do
  1150.     {
  1151.       prt( "<f>ile character description. <c>hange character name.", 21, 2);
  1152.       c = inkey();
  1153.       switch(c)
  1154.     {
  1155.     case 'c':
  1156.       get_name();
  1157.       flag = TRUE;
  1158.       break;
  1159.     case 'f':
  1160. #ifdef MAC
  1161.       /* On mac, file_character() gets filename with std file dialog. */
  1162.       if (file_character ())
  1163.         flag = TRUE;
  1164. #else
  1165.       prt ("File name:", 0, 0);
  1166.       if (get_string (temp, 0, 10, 60) && temp[0])
  1167.         if (file_character (temp))
  1168.           flag = TRUE;
  1169. #endif
  1170.       break;
  1171.     case ESCAPE: case ' ':
  1172.     case '\n': case '\r':
  1173.       flag = TRUE;
  1174.       break;
  1175.     default:
  1176.       bell ();
  1177.       break;
  1178.     }
  1179.     }
  1180.   while (!flag);
  1181. }
  1182.  
  1183.  
  1184. /* Destroy an item in the inventory            -RAK-    */
  1185. void inven_destroy(item_val)
  1186. int item_val;
  1187. {
  1188.   register int j;
  1189.   register inven_type *i_ptr;
  1190. #ifdef ATARIST_MWC
  1191.   int32u holder;
  1192. #endif
  1193.  
  1194.   i_ptr = &inventory[item_val];
  1195.   if ((i_ptr->number > 1) && (i_ptr->subval <= ITEM_SINGLE_STACK_MAX))
  1196.     {
  1197.       i_ptr->number--;
  1198.       inven_weight -= i_ptr->weight;
  1199.     }
  1200.   else
  1201.     {
  1202.       inven_weight -= i_ptr->weight*i_ptr->number;
  1203.       for (j = item_val; j < inven_ctr-1; j++)
  1204.     inventory[j] = inventory[j+1];
  1205.       invcopy(&inventory[inven_ctr-1], OBJ_NOTHING);
  1206.       inven_ctr--;
  1207.     }
  1208. #ifdef ATARIST_MWC
  1209.   py.flags.status |= (holder = PY_STR_WGT);
  1210. #else
  1211.   py.flags.status |= PY_STR_WGT;
  1212. #endif
  1213. }
  1214.  
  1215.  
  1216. /* Copies the object in the second argument over the first argument.
  1217.    However, the second always gets a number of one except for ammo etc. */
  1218. void take_one_item (s_ptr, i_ptr)
  1219. register inven_type *s_ptr, *i_ptr;
  1220. {
  1221.   *s_ptr = *i_ptr;
  1222.   if ((s_ptr->number > 1) && (s_ptr->subval >= ITEM_SINGLE_STACK_MIN)
  1223.       && (s_ptr->subval <= ITEM_SINGLE_STACK_MAX))
  1224.     s_ptr->number = 1;
  1225. }
  1226.  
  1227.  
  1228. /* Drops an item from inventory to given location    -RAK-    */
  1229. void inven_drop(item_val, drop_all)
  1230. register int item_val, drop_all;
  1231. {
  1232.   int i;
  1233.   register inven_type *i_ptr;
  1234.   vtype prt2;
  1235.   bigvtype prt1;
  1236. #ifdef ATARIST_MWC
  1237.   int32u holder;
  1238. #endif
  1239.  
  1240.   if (cave[char_row][char_col].tptr != 0)
  1241.     (void) delete_object(char_row, char_col);
  1242.   i = popt ();
  1243.   i_ptr = &inventory[item_val];
  1244.   t_list[i] = *i_ptr;
  1245.   cave[char_row][char_col].tptr = i;
  1246.  
  1247.   if (item_val >= INVEN_WIELD)
  1248.     takeoff (item_val, -1);
  1249.   else
  1250.     {
  1251.       if (drop_all || i_ptr->number == 1)
  1252.     {
  1253.       inven_weight -= i_ptr->weight*i_ptr->number;
  1254.       inven_ctr--;
  1255.       while (item_val < inven_ctr)
  1256.         {
  1257.           inventory[item_val] = inventory[item_val+1];
  1258.           item_val++;
  1259.         }
  1260.       invcopy(&inventory[inven_ctr], OBJ_NOTHING);
  1261.     }
  1262.       else
  1263.     {
  1264.       t_list[i].number = 1;
  1265.       inven_weight -= i_ptr->weight;
  1266.       i_ptr->number--;
  1267.     }
  1268.       objdes (prt1, &t_list[i], TRUE);
  1269.       (void) sprintf (prt2, "Dropped %s", prt1);
  1270.       msg_print (prt2);
  1271.     }
  1272. #ifdef ATARIST_MWC
  1273.   py.flags.status |= (holder = PY_STR_WGT);
  1274. #else
  1275.   py.flags.status |= PY_STR_WGT;
  1276. #endif
  1277. }
  1278.  
  1279.  
  1280. /* Destroys a type of item on a given percent chance    -RAK-    */
  1281. int inven_damage(typ, perc)
  1282. int (*typ)();
  1283. register int perc;
  1284. {
  1285.   register int i, j;
  1286.  
  1287.   j = 0;
  1288.   for (i = 0; i < inven_ctr; i++)
  1289.     if ((*typ)(&inventory[i]) && (randint(100) < perc))
  1290.       {
  1291.     inven_destroy(i);
  1292.     j++;
  1293.       }
  1294.   return(j);
  1295. }
  1296.  
  1297.  
  1298. /* Computes current weight limit            -RAK-    */
  1299. int weight_limit()
  1300. {
  1301.   register int weight_cap;
  1302.  
  1303.   weight_cap = py.stats.use_stat[A_STR] * PLAYER_WEIGHT_CAP + py.misc.wt;
  1304.   if (weight_cap > 3000)  weight_cap = 3000;
  1305.   return(weight_cap);
  1306. }
  1307.  
  1308.  
  1309. /* this code must be identical to the inven_carry() code below */
  1310. int inven_check_num (t_ptr)
  1311. register inven_type *t_ptr;
  1312. {
  1313.   register int i;
  1314.  
  1315.   if (inven_ctr < INVEN_WIELD)
  1316.     return TRUE;
  1317.   else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN)
  1318.     for (i = 0; i < inven_ctr; i++)
  1319.       if (inventory[i].tval == t_ptr->tval &&
  1320.       inventory[i].subval == t_ptr->subval &&
  1321.       /* make sure the number field doesn't overflow */
  1322.       ((int)inventory[i].number + (int)t_ptr->number < 256) &&
  1323.       /* they always stack (subval < 192), or else they have same p1 */
  1324.       ((t_ptr->subval < ITEM_GROUP_MIN) || (inventory[i].p1 == t_ptr->p1))
  1325.       /* only stack if both or neither are identified */
  1326.       && (known1_p(&inventory[i]) == known1_p(t_ptr)))
  1327.     return TRUE;
  1328.   return FALSE;
  1329. }
  1330.  
  1331. /* return FALSE if picking up an object would change the players speed */
  1332. int inven_check_weight(i_ptr)
  1333. register inven_type *i_ptr;
  1334. {
  1335.   register int i, new_inven_weight;
  1336.  
  1337.   i = weight_limit();
  1338.   new_inven_weight = i_ptr->number*i_ptr->weight + inven_weight;
  1339.   if (i < new_inven_weight)
  1340.     i = new_inven_weight / (i + 1);
  1341.   else
  1342.     i = 0;
  1343.  
  1344.   if (pack_heavy != i)
  1345.     return FALSE;
  1346.   else
  1347.     return TRUE;
  1348. }
  1349.  
  1350.  
  1351. /* Are we strong enough for the current pack and weapon?  -CJS-     */
  1352. void check_strength()
  1353. {
  1354.   register int i;
  1355.   register inven_type *i_ptr;
  1356. #ifdef ATARIST_MWC
  1357.   int32u holder;
  1358. #endif
  1359.  
  1360.   i_ptr = &inventory[INVEN_WIELD];
  1361.   if (i_ptr->tval != TV_NOTHING
  1362.       && (py.stats.use_stat[A_STR]*15 < i_ptr->weight))
  1363.     {
  1364.       if (weapon_heavy == FALSE)
  1365.     {
  1366.       msg_print("You have trouble wielding such a heavy weapon.");
  1367.       weapon_heavy = TRUE;
  1368.       calc_bonuses();
  1369.     }
  1370.     }
  1371.   else if (weapon_heavy == TRUE)
  1372.     {
  1373.       weapon_heavy = FALSE;
  1374.       if (i_ptr->tval != TV_NOTHING)
  1375.     msg_print("You are strong enough to wield your weapon.");
  1376.       calc_bonuses();
  1377.     }
  1378.   i = weight_limit();
  1379.   if (i < inven_weight)
  1380.     i = inven_weight / (i+1);
  1381.   else
  1382.     i = 0;
  1383.   if (pack_heavy != i)
  1384.     {
  1385.       if (pack_heavy < i)
  1386.     msg_print("Your pack is so heavy that it slows you down.");
  1387.       else
  1388.     msg_print("You move more easily under the weight of your pack.");
  1389.       change_speed(i - pack_heavy);
  1390.       pack_heavy = i;
  1391.     }
  1392. #ifdef ATARIST_MWC
  1393.   py.flags.status &= ~(holder = PY_STR_WGT);
  1394. #else
  1395.   py.flags.status &= ~PY_STR_WGT;
  1396. #endif
  1397. }
  1398.  
  1399.  
  1400. /* Add an item to players inventory.  Return the    */
  1401. /* item position for a description if needed.           -RAK-   */
  1402. /* this code must be identical to the inven_check_num() code above */
  1403. int inven_carry(i_ptr)
  1404. register inven_type *i_ptr;
  1405. {
  1406.   register int locn, i;
  1407.   register int typ, subt;
  1408.   register inven_type *t_ptr;
  1409.   int known1p, always_known1p;
  1410. #ifdef ATARIST_MWC
  1411.   int32u holder;
  1412. #endif
  1413.  
  1414.   typ = i_ptr->tval;
  1415.   subt = i_ptr->subval;
  1416.   known1p = known1_p (i_ptr);
  1417.   always_known1p = (object_offset (i_ptr) == -1);
  1418.   /* Now, check to see if player can carry object  */
  1419.   for (locn = 0; ; locn++)
  1420.     {
  1421.       t_ptr = &inventory[locn];
  1422.       if ((typ == t_ptr->tval) && (subt == t_ptr->subval)
  1423.       && (subt >= ITEM_SINGLE_STACK_MIN) &&
  1424.       ((int)t_ptr->number + (int)i_ptr->number < 256) &&
  1425.       ((subt < ITEM_GROUP_MIN) || (t_ptr->p1 == i_ptr->p1)) &&
  1426.       /* only stack if both or neither are identified */
  1427.       (known1p == known1_p(t_ptr)))
  1428.     {
  1429.       t_ptr->number += i_ptr->number;
  1430.       break;
  1431.     }
  1432.       /* For items which are always known1p, i.e. never have a 'color',
  1433.      insert them into the inventory in sorted order.  */
  1434.       else if ((typ == t_ptr->tval && subt < t_ptr->subval
  1435.         && always_known1p)
  1436.            || (typ > t_ptr->tval))
  1437.     {
  1438.       for (i = inven_ctr - 1; i >= locn; i--)
  1439.         inventory[i+1] = inventory[i];
  1440.       inventory[locn] = *i_ptr;
  1441.       inven_ctr++;
  1442.       break;
  1443.     }
  1444.     }
  1445.  
  1446.   inven_weight += i_ptr->number*i_ptr->weight;
  1447. #ifdef ATARIST_MWC
  1448.   py.flags.status |= (holder = PY_STR_WGT);
  1449. #else
  1450.   py.flags.status |= PY_STR_WGT;
  1451. #endif
  1452.   return locn;
  1453. }
  1454.  
  1455.  
  1456. /* Returns spell chance of failure for spell        -RAK-    */
  1457. int spell_chance(spell)
  1458. int spell;
  1459. {
  1460.   register spell_type *s_ptr;
  1461.   register int chance;
  1462.   register int stat;
  1463.  
  1464.   s_ptr = &magic_spell[py.misc.pclass-1][spell];
  1465.   chance = s_ptr->sfail - 3*(py.misc.lev-s_ptr->slevel);
  1466.   if (class[py.misc.pclass].spell == MAGE)
  1467.     stat = A_INT;
  1468.   else
  1469.     stat = A_WIS;
  1470.   chance -= 3 * (stat_adj(stat)-1);
  1471.   if (s_ptr->smana > py.misc.cmana)
  1472.     chance += 5 * (s_ptr->smana-py.misc.cmana);
  1473.   if (chance > 95)
  1474.     chance = 95;
  1475.   else if (chance < 5)
  1476.     chance = 5;
  1477.   return chance;
  1478. }
  1479.  
  1480.  
  1481. /* Print list of spells                    -RAK-    */
  1482. /* if nonconsec is -1: spells numbered consecutively from 'a' to 'a'+num
  1483.                   >=0: spells numbered by offset from nonconsec */
  1484. void print_spells(spell, num, comment, nonconsec)
  1485. int *spell;
  1486. register int num;
  1487. int comment, nonconsec;
  1488. {
  1489.   register int i, j;
  1490.   vtype out_val;
  1491.   register spell_type *s_ptr;
  1492.   int col, offset;
  1493.   char *p;
  1494.   char spell_char;
  1495.  
  1496.   if (comment)
  1497.     col = 22;
  1498.   else
  1499.     col = 31;
  1500.   offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
  1501.   erase_line(1, col);
  1502.   put_buffer("Name", 1, col+5);
  1503.   put_buffer("Lv Mana Fail", 1, col+35);
  1504.   /* only show the first 22 choices */
  1505.   if (num > 22)
  1506.     num = 22;
  1507.   for (i = 0; i < num; i++)
  1508.     {
  1509.       j = spell[i];
  1510.       s_ptr = &magic_spell[py.misc.pclass-1][j];
  1511.       if (comment == FALSE)
  1512.     p = "";
  1513.       else if ((spell_forgotten & (1L << j)) != 0)
  1514.     p = " forgotten";
  1515.       else if ((spell_learned & (1L << j)) == 0)
  1516.     p = " unknown";
  1517.       else if ((spell_worked & (1L << j)) == 0)
  1518.     p = " untried";
  1519.       else
  1520.     p = "";
  1521.       /* determine whether or not to leave holes in character choices,
  1522.      nonconsec -1 when learning spells, consec offset>=0 when asking which
  1523.      spell to cast */
  1524.       if (nonconsec == -1)
  1525.     spell_char = 'a' + i;
  1526.       else
  1527.     spell_char = 'a' + j - nonconsec;
  1528.       (void) sprintf(out_val, "  %c) %-30s%2d %4d %3d%%%s", spell_char,
  1529.              spell_names[j+offset], s_ptr->slevel, s_ptr->smana,
  1530.              spell_chance (j), p);
  1531.       prt(out_val, 2+i, col);
  1532.     }
  1533. }
  1534.  
  1535.  
  1536. /* Returns spell pointer                -RAK-    */
  1537. int get_spell(spell, num, sn, sc, prompt, first_spell)
  1538. int *spell;
  1539. register int num;
  1540. register int *sn, *sc;
  1541. char *prompt;
  1542. int first_spell;
  1543. {
  1544.   register spell_type *s_ptr;
  1545.   int flag, redraw, offset, i;
  1546.   char choice;
  1547.   vtype out_str, tmp_str;
  1548.  
  1549.   *sn = -1;
  1550.   flag = FALSE;
  1551.   (void) sprintf(out_str, "(Spells %c-%c, *=List, <ESCAPE>=exit) %s",
  1552.          spell[0]+'a'-first_spell, spell[num-1]+'a'-first_spell,
  1553.          prompt);
  1554.   redraw = FALSE;
  1555.   offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
  1556.   while (flag == FALSE && get_com (out_str, &choice))
  1557.     {
  1558.       if (isupper((int)choice))
  1559.     {
  1560.       *sn = choice-'A'+first_spell;
  1561.       /* verify that this is in spell[], at most 22 entries in spell[] */
  1562.       for (i = 0; i < num; i++)
  1563.         if (*sn == spell[i])
  1564.           break;
  1565.       if (i == num)
  1566.         *sn = -2;
  1567.       else
  1568.         {
  1569.           s_ptr = &magic_spell[py.misc.pclass-1][*sn];
  1570.           (void) sprintf (tmp_str, "Cast %s (%d mana, %d%% fail)?",
  1571.                   spell_names[*sn+offset], s_ptr->smana,
  1572.                   spell_chance (*sn));
  1573.           if (get_check (tmp_str))
  1574.         flag = TRUE;
  1575.           else
  1576.         *sn = -1;
  1577.         }
  1578.     }
  1579.       else if (islower((int)choice))
  1580.     {
  1581.       *sn = choice-'a'+first_spell;
  1582.       /* verify that this is in spell[], at most 22 entries in spell[] */
  1583.       for (i = 0; i < num; i++)
  1584.         if (*sn == spell[i])
  1585.           break;
  1586.       if (i == num)
  1587.         *sn = -2;
  1588.       else
  1589.         flag = TRUE;
  1590.     }
  1591.       else if (choice == '*')
  1592.     {
  1593.       /* only do this drawing once */
  1594.       if (!redraw)
  1595.         {
  1596.           save_screen ();
  1597.           redraw = TRUE;
  1598.           print_spells (spell, num, FALSE, first_spell);
  1599.         }
  1600.     }
  1601.       else if (isalpha((int)choice))
  1602.     *sn = -2;
  1603.       else
  1604.     {
  1605.       *sn = -1;
  1606.       bell();
  1607.     }
  1608.       if (*sn == -2)
  1609.     {
  1610.       (void) sprintf (tmp_str, "You don't know that %s.",
  1611.               (offset == SPELL_OFFSET ? "spell" : "prayer"));
  1612.       msg_print(tmp_str);
  1613.     }
  1614.     }
  1615.   if (redraw)
  1616.     restore_screen ();
  1617.  
  1618.   erase_line(MSG_LINE, 0);
  1619.   if (flag)
  1620.     *sc = spell_chance (*sn);
  1621.  
  1622.   return(flag);
  1623. }
  1624.  
  1625.  
  1626. /* calculate number of spells player should have, and learn forget spells
  1627.    until that number is met -JEW- */
  1628. void calc_spells(stat)
  1629. int stat;
  1630. {
  1631.   register int i;
  1632.   register int32u mask;
  1633.   int32u spell_flag;
  1634.   int j, offset;
  1635.   int num_allowed, new_spells, num_known, levels;
  1636.   vtype tmp_str;
  1637.   char *p;
  1638.   register struct misc *p_ptr;
  1639.   register spell_type *msp_ptr;
  1640.  
  1641.   p_ptr = &py.misc;
  1642.   msp_ptr = &magic_spell[p_ptr->pclass-1][0];
  1643.   if (stat == A_INT)
  1644.     {
  1645.       p = "spell";
  1646.       offset = SPELL_OFFSET;
  1647.     }
  1648.   else
  1649.     {
  1650.       p = "prayer";
  1651.       offset = PRAYER_OFFSET;
  1652.     }
  1653.  
  1654.   /* check to see if know any spells greater than level, eliminate them */
  1655.   for (i = 31, mask = 0x80000000L; mask; mask >>= 1, i--)
  1656.     if (mask & spell_learned)
  1657.       {
  1658.     if (msp_ptr[i].slevel > p_ptr->lev)
  1659.       {
  1660.         spell_learned &= ~mask;
  1661.         spell_forgotten |= mask;
  1662.         (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  1663.                spell_names[i+offset]);
  1664.         msg_print(tmp_str);
  1665.       }
  1666.     else
  1667.       break;
  1668.       }
  1669.  
  1670.   /* calc number of spells allowed */
  1671.   levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
  1672.   switch(stat_adj(stat))
  1673.     {
  1674.     case 0:            num_allowed = 0; break;
  1675.     case 1: case 2: case 3: num_allowed = 1 * levels; break;
  1676.     case 4: case 5:        num_allowed = 3 * levels / 2; break;
  1677.     case 6:            num_allowed = 2 * levels; break;
  1678.     case 7:            num_allowed = 5 * levels / 2; break;
  1679.     }
  1680.  
  1681.   num_known = 0;
  1682.   for (mask = 0x1; mask; mask <<= 1)
  1683.     if (mask & spell_learned)
  1684.       num_known++;
  1685.   new_spells = num_allowed - num_known;
  1686.  
  1687.   if (new_spells > 0)
  1688.     {
  1689.       /* remember forgotten spells while forgotten spells exist of new_spells
  1690.      positive, remember the spells in the order that they were learned */
  1691.       for (i = 0; (spell_forgotten && new_spells
  1692.            && (i < num_allowed) && (i < 32)); i++)
  1693.     {
  1694.       /* j is (i+1)th spell learned */
  1695.       j = spell_order[i];
  1696.       /* shifting by amounts greater than number of bits in long gives
  1697.          an undefined result, so don't shift for unknown spells */
  1698.       if (j == 99)
  1699.         mask = 0x0;
  1700.       else
  1701.         mask = 1L << j;
  1702.       if (mask & spell_forgotten)
  1703.         {
  1704.           if (msp_ptr[j].slevel <= p_ptr->lev)
  1705.         {
  1706.           new_spells--;
  1707.           spell_forgotten &= ~mask;
  1708.           spell_learned |= mask;
  1709.           (void) sprintf(tmp_str, "You have remembered the %s of %s.",
  1710.                  p, spell_names[j+offset]);
  1711.           msg_print(tmp_str);
  1712.         }
  1713.           else
  1714.         num_allowed++;
  1715.         }
  1716.     }
  1717.  
  1718.       if (new_spells > 0)
  1719.     {
  1720.       /* determine which spells player can learn */
  1721.       /* must check all spells here, in gain_spell() we actually check
  1722.          if the books are present */
  1723.       spell_flag = 0x7FFFFFFFL & ~spell_learned;
  1724.  
  1725.       mask = 0x1;
  1726.       i = 0;
  1727.       for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
  1728.         if (spell_flag & mask)
  1729.           {
  1730.         spell_flag &= ~mask;
  1731.         if (msp_ptr[j].slevel <= p_ptr->lev)
  1732.           i++;
  1733.           }
  1734.  
  1735.       if (new_spells > i)
  1736.         new_spells = i;
  1737.     }
  1738.     }
  1739.   else if (new_spells < 0)
  1740.     {
  1741.       /* forget spells until new_spells zero or no more spells know, spells
  1742.      are forgotten in the opposite order that they were learned */
  1743.       for (i = 31; new_spells && spell_learned; i--)
  1744.     {
  1745.       /* j is the (i+1)th spell learned */
  1746.       j = spell_order[i];
  1747.       /* shifting by amounts greater than number of bits in long gives
  1748.          an undefined result, so don't shift for unknown spells */
  1749.       if (j == 99)
  1750.         mask = 0x0;
  1751.       else
  1752.         mask = 1L << j;
  1753.       if (mask & spell_learned)
  1754.         {
  1755.           spell_learned &= ~mask;
  1756.           spell_forgotten |= mask;
  1757.           new_spells++;
  1758.           (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  1759.                  spell_names[j+offset]);
  1760.           msg_print(tmp_str);
  1761.         }
  1762.     }
  1763.  
  1764.       new_spells = 0;
  1765.     }
  1766.  
  1767.   if (new_spells != py.flags.new_spells)
  1768.     {
  1769.       if (new_spells > 0 && py.flags.new_spells == 0)
  1770.     {
  1771.       (void) sprintf(tmp_str, "You can learn some new %ss now.", p);
  1772.       msg_print(tmp_str);
  1773.     }
  1774.  
  1775.       py.flags.new_spells = new_spells;
  1776.       py.flags.status |= PY_STUDY;
  1777.     }
  1778. }
  1779.  
  1780.  
  1781. /* gain spells when player wants to        - jw */
  1782. void gain_spells()
  1783. {
  1784.   char query;
  1785.   int stat, diff_spells, new_spells;
  1786.   int spells[31], offset, last_known;
  1787.   register int i, j;
  1788.   register int32u spell_flag, mask;
  1789.   vtype tmp_str;
  1790.   struct misc *p_ptr;
  1791.   register spell_type *msp_ptr;
  1792.  
  1793.   /* Priests don't need light because they get spells from their god,
  1794.      so only fail when can't see if player has MAGE spells.  This check
  1795.      is done below.  */
  1796.   if (py.flags.confused > 0)
  1797.     {
  1798.       msg_print("You are too confused.");
  1799.       return;
  1800.     }
  1801.  
  1802.   new_spells = py.flags.new_spells;
  1803.   diff_spells = 0;
  1804.   p_ptr = &py.misc;
  1805.   msp_ptr = &magic_spell[p_ptr->pclass-1][0];
  1806.   if (class[p_ptr->pclass].spell == MAGE)
  1807.     {
  1808.       stat = A_INT;
  1809.       offset = SPELL_OFFSET;
  1810.  
  1811.       /* People with MAGE spells can't learn spells if they can't read their
  1812.      books.  */
  1813.       if (py.flags.blind > 0)
  1814.     {
  1815.       msg_print("You can't see to read your spell book!");
  1816.       return;
  1817.     }
  1818.       else if (no_light())
  1819.     {
  1820.       msg_print("You have no light to read by.");
  1821.       return;
  1822.     }
  1823.     }
  1824.   else
  1825.     {
  1826.       stat = A_WIS;
  1827.       offset = PRAYER_OFFSET;
  1828.     }
  1829.  
  1830.   for (last_known = 0; last_known < 32; last_known++)
  1831.     if (spell_order[last_known] == 99)
  1832.       break;
  1833.  
  1834.   if (!new_spells)
  1835.     {
  1836.       (void) sprintf(tmp_str, "You can't learn any new %ss!",
  1837.              (stat == A_INT ? "spell" : "prayer"));
  1838.       msg_print(tmp_str);
  1839.       free_turn_flag = TRUE;
  1840.     }
  1841.   else
  1842.     {
  1843.       /* determine which spells player can learn */
  1844.       /* mages need the book to learn a spell, priests do not need the book */
  1845.       if (stat == A_INT)
  1846.     {
  1847.       spell_flag = 0;
  1848.       for (i = 0; i < inven_ctr; i++)
  1849.         if (inventory[i].tval == TV_MAGIC_BOOK)
  1850.           spell_flag |= inventory[i].flags;
  1851.     }
  1852.       else
  1853.     spell_flag = 0x7FFFFFFF;
  1854.  
  1855.       /* clear bits for spells already learned */
  1856.       spell_flag &= ~spell_learned;
  1857.  
  1858.       mask = 0x1;
  1859.       i = 0;
  1860.       for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
  1861.     if (spell_flag & mask)
  1862.       {
  1863.         spell_flag &= ~mask;
  1864.         if (msp_ptr[j].slevel <= p_ptr->lev)
  1865.           {
  1866.         spells[i] = j;
  1867.         i++;
  1868.           }
  1869.       }
  1870.  
  1871.       if (new_spells > i)
  1872.     {
  1873.       msg_print("You seem to be missing a book.");
  1874.       diff_spells = new_spells - i;
  1875.       new_spells = i;
  1876.     }
  1877.       if (new_spells == 0)
  1878.     ;
  1879.       else if (stat == A_INT)
  1880.     {
  1881.       /* get to choose which mage spells will be learned */
  1882.       save_screen();
  1883.       print_spells (spells, i, FALSE, -1);
  1884.       while (new_spells && get_com ("Learn which spell?", &query))
  1885.         {
  1886.           j = query - 'a';
  1887.           /* test j < 23 in case i is greater than 22, only 22 spells
  1888.          are actually shown on the screen, so limit choice to those */
  1889.           if (j >= 0 && j < i && j < 22)
  1890.         {
  1891.           new_spells--;
  1892.           spell_learned |= 1L << spells[j];
  1893.           spell_order[last_known++] = spells[j];
  1894.           for (; j <= i-1; j++)
  1895.             spells[j] = spells[j+1];
  1896.           i--;
  1897.           erase_line (j+1, 31);
  1898.           print_spells (spells, i, FALSE, -1);
  1899.         }
  1900.           else
  1901.         bell();
  1902.         }
  1903.       restore_screen();
  1904.     }
  1905.       else
  1906.     {
  1907.       /* pick a prayer at random */
  1908.       while (new_spells)
  1909.         {
  1910.           j = randint(i) - 1;
  1911.           spell_learned |= 1L << spells[j];
  1912.           spell_order[last_known++] = spells[j];
  1913.           (void) sprintf (tmp_str,
  1914.                   "You have learned the prayer of %s.",
  1915.                   spell_names[spells[j]+offset]);
  1916.           msg_print(tmp_str);
  1917.           for (; j <= i-1; j++)
  1918.         spells[j] = spells[j+1];
  1919.           i--;
  1920.           new_spells--;
  1921.         }
  1922.     }
  1923.       py.flags.new_spells = new_spells + diff_spells;
  1924.       if (py.flags.new_spells == 0)
  1925.     py.flags.status |= PY_STUDY;
  1926.       /* set the mana for first level characters when they learn their
  1927.      first spell */
  1928.       if (py.misc.mana == 0)
  1929.     calc_mana(stat);
  1930.     }
  1931. }
  1932.  
  1933.  
  1934. /* Gain some mana if you know at least one spell    -RAK-    */
  1935. void calc_mana(stat)
  1936. int stat;
  1937. {
  1938.   register int new_mana, levels;
  1939.   register struct misc *p_ptr;
  1940.   register int32 value;
  1941. #ifdef ATARIST_MWC
  1942.   int32u holder;
  1943. #endif
  1944.  
  1945.   p_ptr = &py.misc;
  1946.   if (spell_learned != 0)
  1947.     {
  1948.       levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
  1949.       switch(stat_adj(stat))
  1950.     {
  1951.     case 0: new_mana = 0; break;
  1952.     case 1: case 2: new_mana = 1 * levels; break;
  1953.     case 3: new_mana = 3 * levels / 2; break;
  1954.     case 4: new_mana = 2 * levels; break;
  1955.     case 5: new_mana = 5 * levels / 2; break;
  1956.     case 6: new_mana = 3 * levels; break;
  1957.     case 7: new_mana = 4 * levels; break;
  1958.     }
  1959.       /* increment mana by one, so that first level chars have 2 mana */
  1960.       if (new_mana > 0)
  1961.     new_mana++;
  1962.  
  1963.       /* mana can be zero when creating character */
  1964.       if (p_ptr->mana != new_mana)
  1965.     {
  1966.       if (p_ptr->mana != 0)
  1967.         {
  1968.           /* change current mana proportionately to change of max mana,
  1969.          divide first to avoid overflow, little loss of accuracy */
  1970.           value = (((long)p_ptr->cmana << 16) + p_ptr->cmana_frac)
  1971.         / p_ptr->mana * new_mana;
  1972.           p_ptr->cmana = value >> 16;
  1973.           p_ptr->cmana_frac = value & 0xFFFF;
  1974.         }
  1975.       else
  1976.         {
  1977.           p_ptr->cmana = new_mana;
  1978.           p_ptr->cmana_frac = 0;
  1979.         }
  1980.       p_ptr->mana = new_mana;
  1981.       /* can't print mana here, may be in store or inventory mode */
  1982. #ifdef ATARIST_MWC
  1983.       py.flags.status |= (holder = PY_MANA);
  1984. #else
  1985.       py.flags.status |= PY_MANA;
  1986. #endif
  1987.     }
  1988.     }
  1989.   else if (p_ptr->mana != 0)
  1990.     {
  1991.       p_ptr->mana = 0;
  1992.       p_ptr->cmana = 0;
  1993.       /* can't print mana here, may be in store or inventory mode */
  1994. #ifdef ATARIST_MWC
  1995.       py.flags.status |= (holder = PY_MANA);
  1996. #else
  1997.       py.flags.status |= PY_MANA;
  1998. #endif
  1999.     }
  2000. }
  2001.  
  2002.  
  2003. /* Increases hit points and level            -RAK-    */
  2004. static void gain_level()
  2005. {
  2006.   register int32 dif_exp, need_exp;
  2007.   vtype out_val;
  2008.   register struct misc *p_ptr;
  2009.   register class_type *c_ptr;
  2010.  
  2011.   p_ptr = &py.misc;
  2012.   p_ptr->lev++;
  2013.   (void) sprintf(out_val, "Welcome to level %d.", (int)p_ptr->lev);
  2014.   msg_print(out_val);
  2015.   calc_hitpoints();
  2016.  
  2017.   need_exp = player_exp[p_ptr->lev-1] * p_ptr->expfact / 100;
  2018.   if (p_ptr->exp > need_exp)
  2019.     {
  2020.       /* lose some of the 'extra' exp when gain a level */
  2021.       dif_exp = p_ptr->exp - need_exp;
  2022.       p_ptr->exp = need_exp + (dif_exp / 2);
  2023.     }
  2024.   prt_level();
  2025.   prt_title();
  2026.   c_ptr = &class[p_ptr->pclass];
  2027.   if (c_ptr->spell == MAGE)
  2028.     {
  2029.       calc_spells(A_INT);
  2030.       calc_mana(A_INT);
  2031.     }
  2032.   else if (c_ptr->spell == PRIEST)
  2033.     {
  2034.       calc_spells(A_WIS);
  2035.       calc_mana(A_WIS);
  2036.     }
  2037. }
  2038.  
  2039. /* Prints experience                    -RAK-    */
  2040. void prt_experience()
  2041. {
  2042.   register struct misc *p_ptr;
  2043.  
  2044.   p_ptr = &py.misc;
  2045.   if (p_ptr->exp > MAX_EXP)
  2046.     p_ptr->exp = MAX_EXP;
  2047.  
  2048.   if (p_ptr->lev < MAX_PLAYER_LEVEL)
  2049.     while ((player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp)
  2050.       gain_level();
  2051.  
  2052.   if (p_ptr->exp > p_ptr->max_exp)
  2053.     p_ptr->max_exp = p_ptr->exp;
  2054.  
  2055.   prt_long(p_ptr->exp, 14, STAT_COLUMN+6);
  2056. }
  2057.  
  2058.  
  2059. /* Calculate the players hit points */
  2060. void calc_hitpoints()
  2061. {
  2062.   register int hitpoints;
  2063.   register struct misc *p_ptr;
  2064.   register int32 value;
  2065. #ifdef ATARIST_MWC
  2066.   int32u holder;
  2067. #endif
  2068.  
  2069.   p_ptr = &py.misc;
  2070.   hitpoints = player_hp[p_ptr->lev-1] + (con_adj() * p_ptr->lev);
  2071.   /* always give at least one point per level + 1 */
  2072.   if (hitpoints < (p_ptr->lev + 1))
  2073.     hitpoints = p_ptr->lev + 1;
  2074.  
  2075.   if (py.flags.status & PY_HERO)
  2076.     hitpoints += 10;
  2077.   if (py.flags.status & PY_SHERO)
  2078.     hitpoints += 20;
  2079.  
  2080.   /* mhp can equal zero while character is being created */
  2081.   if ((hitpoints != p_ptr->mhp) && (p_ptr->mhp != 0))
  2082.     {
  2083.       /* change current hit points proportionately to change of mhp,
  2084.      divide first to avoid overflow, little loss of accuracy */
  2085.       value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp
  2086.     * hitpoints;
  2087.       p_ptr->chp = value >> 16;
  2088.       p_ptr->chp_frac = value & 0xFFFF;
  2089.       p_ptr->mhp = hitpoints;
  2090.  
  2091.       /* can't print hit points here, may be in store or inventory mode */
  2092. #ifdef ATARIST_MWC
  2093.       py.flags.status |= (holder = PY_HP);
  2094. #else
  2095.       py.flags.status |= PY_HP;
  2096. #endif
  2097.     }
  2098. }
  2099.  
  2100.  
  2101. /* Inserts a string into a string                */
  2102. void insert_str(object_str, mtc_str, insert)
  2103. char *object_str, *mtc_str, *insert;
  2104. {
  2105.   int obj_len;
  2106.   char *bound, *pc;
  2107.   register int i, mtc_len;
  2108.   register char *temp_obj, *temp_mtc;
  2109.   char out_val[80];
  2110.  
  2111.   mtc_len = strlen(mtc_str);
  2112.   obj_len = strlen(object_str);
  2113.   bound = object_str + obj_len - mtc_len;
  2114.   for (pc = object_str; pc <= bound; pc++)
  2115.     {
  2116.       temp_obj = pc;
  2117.       temp_mtc = mtc_str;
  2118.       for (i = 0; i < mtc_len; i++)
  2119.     if (*temp_obj++ != *temp_mtc++)
  2120.       break;
  2121.       if (i == mtc_len)
  2122.     break;
  2123.     }
  2124.  
  2125.   if (pc <= bound)
  2126.     {
  2127. #ifdef __TURBOC__
  2128.       /* Avoid complaint about possible loss of significance.  */
  2129.       (void) strncpy(out_val, object_str, (size_t)(pc-object_str));
  2130. #else
  2131.       (void) strncpy(out_val, object_str, (pc-object_str));
  2132. #endif
  2133.       /* Turbo C needs int for array index.  */
  2134.       out_val[(int)(pc-object_str)] = '\0';
  2135.       if (insert)
  2136.     (void) strcat(out_val, insert);
  2137.       (void) strcat(out_val, (char *)(pc+mtc_len));
  2138.       (void) strcpy(object_str, out_val);
  2139.     }
  2140. }
  2141.  
  2142.  
  2143. #if 0
  2144. /* this is no longer used anywhere */
  2145. /* Inserts a number into a string                */
  2146. void insert_num(object_str, mtc_str, number, show_sign)
  2147. char *object_str;
  2148. register char *mtc_str;
  2149. int number;
  2150. int show_sign;
  2151. {
  2152.   int mlen;
  2153.   vtype str1, str2;
  2154.   register char *string, *tmp_str;
  2155.   int flag;
  2156.  
  2157.   flag = 1;
  2158.   mlen = strlen(mtc_str);
  2159.   tmp_str = object_str;
  2160.   do
  2161.     {
  2162.       string = index(tmp_str, mtc_str[0]);
  2163.       if (string == CNIL)
  2164.     flag = 0;
  2165.       else
  2166.     {
  2167.       flag = strncmp(string, mtc_str, mlen);
  2168.       if (flag)
  2169.         tmp_str = string+1;
  2170.     }
  2171.     }
  2172.   while (flag);
  2173.   if (string)
  2174.     {
  2175. #ifdef __TURBOC__
  2176.       /* Avoid complaint about possible loss of significance.  */
  2177.       (void) strncpy(str1, object_str, (size_t)(string - object_str));
  2178. #else
  2179.       (void) strncpy(str1, object_str, string - object_str);
  2180. #endif
  2181.       /* Turbo C needs int for array index.  */
  2182.       str1[(int)(string - object_str)] = '\0';
  2183.       (void) strcpy(str2, string + mlen);
  2184.       if ((number >= 0) && (show_sign))
  2185.     (void) sprintf(object_str, "%s+%d%s", str1, number, str2);
  2186.       else
  2187.     (void) sprintf(object_str, "%s%d%s", str1, number, str2);
  2188.     }
  2189. }
  2190. #endif
  2191.  
  2192. void insert_lnum(object_str, mtc_str, number, show_sign)
  2193. char *object_str;
  2194. register char *mtc_str;
  2195. int32 number;
  2196. int show_sign;
  2197. {
  2198.   int mlen;
  2199.   vtype str1, str2;
  2200.   register char *string, *tmp_str;
  2201.   int flag;
  2202.  
  2203.   flag = 1;
  2204.   mlen = strlen(mtc_str);
  2205.   tmp_str = object_str;
  2206.   do
  2207.     {
  2208.       string = index(tmp_str, mtc_str[0]);
  2209.       if (string == 0)
  2210.     flag = 0;
  2211.       else
  2212.     {
  2213.       flag = strncmp(string, mtc_str, mlen);
  2214.       if (flag)
  2215.         tmp_str = string+1;
  2216.     }
  2217.     }
  2218.   while (flag);
  2219.   if (string)
  2220.     {
  2221.       (void) strncpy(str1, object_str, string - object_str);
  2222.       str1[string - object_str] = '\0';
  2223.       (void) strcpy(str2, string + mlen);
  2224.       if ((number >= 0) && (show_sign))
  2225.     (void) sprintf(object_str, "%s+%ld%s", str1, number, str2);
  2226.       else
  2227.     (void) sprintf(object_str, "%s%ld%s", str1, number, str2);
  2228.     }
  2229. }
  2230.  
  2231.  
  2232. /* lets anyone enter wizard mode after a disclaimer...        - JEW - */
  2233. int enter_wiz_mode()
  2234. {
  2235.   register int answer;
  2236.  
  2237.   if (!noscore)
  2238.     {
  2239.       msg_print("Wizard mode is for debugging and experimenting.");
  2240.       answer = get_check(
  2241.     "The game will not be scored if you enter wizard mode. Are you sure?");
  2242.     }
  2243.   if (noscore || answer)
  2244.     {
  2245.       noscore |= 0x2;
  2246.       wizard = TRUE;
  2247.       return(TRUE);
  2248.     }
  2249.   return(FALSE);
  2250. }
  2251.  
  2252.  
  2253. /* Weapon weight VS strength and dexterity        -RAK-    */
  2254. int attack_blows(weight, wtohit)
  2255. int weight;
  2256. int *wtohit;
  2257. {
  2258.   register int adj_weight;
  2259.   register int str_index, dex_index, s, d;
  2260.  
  2261.   s = py.stats.use_stat[A_STR];
  2262.   d = py.stats.use_stat[A_DEX];
  2263.   if (s * 15 < weight)
  2264.     {
  2265.       *wtohit = s * 15 - weight;
  2266.       return 1;
  2267.     }
  2268.   else
  2269.     {
  2270.       *wtohit = 0;
  2271.       if      (d <  10)     dex_index = 0;
  2272.       else if (d <  19)     dex_index = 1;
  2273.       else if (d <  68)     dex_index = 2;
  2274.       else if (d < 108)     dex_index = 3;
  2275.       else if (d < 118)     dex_index = 4;
  2276.       else         dex_index = 5;
  2277.       adj_weight = (s * 10 / weight);
  2278.       if      (adj_weight < 2)    str_index = 0;
  2279.       else if (adj_weight < 3)    str_index = 1;
  2280.       else if (adj_weight < 4)    str_index = 2;
  2281.       else if (adj_weight < 5)    str_index = 3;
  2282.       else if (adj_weight < 7)    str_index = 4;
  2283.       else if (adj_weight < 9)    str_index = 5;
  2284.       else            str_index = 6;
  2285.       return (int)blows_table[str_index][dex_index];
  2286.     }
  2287. }
  2288.  
  2289.  
  2290. /* Special damage due to magical abilities of object    -RAK-    */
  2291. int tot_dam(i_ptr, tdam, monster)
  2292. register inven_type *i_ptr;
  2293. register int tdam;
  2294. int monster;
  2295. {
  2296.   register creature_type *m_ptr;
  2297.   register recall_type *r_ptr;
  2298. #ifdef ATARIST_MWC
  2299.   int32u holder;
  2300. #endif
  2301.  
  2302. #ifdef ATARIST_MWC
  2303.   if ((i_ptr->flags & (holder = TR_EGO_WEAPON)) &&
  2304. #else
  2305.   if ((i_ptr->flags & TR_EGO_WEAPON) &&
  2306. #endif
  2307.       (((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW)) ||
  2308.        ((i_ptr->tval >= TV_HAFTED) && (i_ptr->tval <= TV_SWORD)) ||
  2309.        (i_ptr->tval == TV_FLASK)))
  2310.     {
  2311.       m_ptr = &c_list[monster];
  2312.       r_ptr = &c_recall[monster];
  2313.       /* Slay Dragon  */
  2314.       if ((m_ptr->cdefense & CD_DRAGON) && (i_ptr->flags & TR_SLAY_DRAGON))
  2315.     {
  2316.       tdam = tdam * 4;
  2317.       r_ptr->r_cdefense |= CD_DRAGON;
  2318.     }
  2319.       /* Slay Undead  */
  2320. #ifdef ATARIST_MWC
  2321.       else if ((m_ptr->cdefense & CD_UNDEAD)
  2322.            && (i_ptr->flags & (holderr = TR_SLAY_UNDEAD)))
  2323. #else
  2324.       else if ((m_ptr->cdefense & CD_UNDEAD)
  2325.            && (i_ptr->flags & TR_SLAY_UNDEAD))
  2326. #endif
  2327.     {
  2328.       tdam = tdam * 3;
  2329.       r_ptr->r_cdefense |= CD_UNDEAD;
  2330.     }
  2331.       /* Slay Animal  */
  2332.       else if ((m_ptr->cdefense & CD_ANIMAL)
  2333.            && (i_ptr->flags & TR_SLAY_ANIMAL))
  2334.     {
  2335.       tdam = tdam * 2;
  2336.       r_ptr->r_cdefense |= CD_ANIMAL;
  2337.     }
  2338.       /* Slay Evil     */
  2339.       else if ((m_ptr->cdefense & CD_EVIL) && (i_ptr->flags & TR_SLAY_EVIL))
  2340.     {
  2341.       tdam = tdam * 2;
  2342.       r_ptr->r_cdefense |= CD_EVIL;
  2343.     }
  2344.       /* Frost           */
  2345. #ifdef ATARIST_MWC
  2346.       else if ((m_ptr->cdefense & CD_FROST)
  2347.            && (i_ptr->flags & (holder = TR_FROST_BRAND)))
  2348. #else
  2349.       else if ((m_ptr->cdefense & CD_FROST)
  2350.            && (i_ptr->flags & TR_FROST_BRAND))
  2351. #endif
  2352.     {
  2353.       tdam = tdam * 3 / 2;
  2354.       r_ptr->r_cdefense |= CD_FROST;
  2355.     }
  2356.       /* Fire          */
  2357. #ifdef ATARIST_MWC
  2358.       else if ((m_ptr->cdefense & CD_FIRE)
  2359.            && (i_ptr->flags & (holder = TR_FLAME_TONGUE)))
  2360. #else
  2361.       else if ((m_ptr->cdefense & CD_FIRE)
  2362.            && (i_ptr->flags & TR_FLAME_TONGUE))
  2363. #endif
  2364.     {
  2365.       tdam = tdam * 3 / 2;
  2366.       r_ptr->r_cdefense |= CD_FIRE;
  2367.     }
  2368.     }
  2369.   return(tdam);
  2370. }
  2371.  
  2372.  
  2373. /* Critical hits, Nasty way to die.            -RAK-    */
  2374. int critical_blow(weight, plus, dam, attack_type)
  2375. register int weight, plus, dam;
  2376. int attack_type;
  2377. {
  2378.   register int critical;
  2379.  
  2380.   critical = dam;
  2381.   /* Weight of weapon, plusses to hit, and character level all        */
  2382.   /* contribute to the chance of a critical               */
  2383.   if (randint(5000) <= (int)(weight + 5 * plus
  2384.                  + (class_level_adj[py.misc.pclass][attack_type]
  2385.                 * py.misc.lev)))
  2386.     {
  2387.       weight += randint(650);
  2388.       if (weight < 400)
  2389.     {
  2390.       critical = 2*dam + 5;
  2391.       msg_print("It was a good hit! (x2 damage)");
  2392.     }
  2393.       else if (weight < 700)
  2394.     {
  2395.       critical = 3*dam + 10;
  2396.       msg_print("It was an excellent hit! (x3 damage)");
  2397.     }
  2398.       else if (weight < 900)
  2399.     {
  2400.       critical = 4*dam + 15;
  2401.       msg_print("It was a superb hit! (x4 damage)");
  2402.     }
  2403.       else
  2404.     {
  2405.       critical = 5*dam + 20;
  2406.       msg_print("It was a *GREAT* hit! (x5 damage)");
  2407.     }
  2408.     }
  2409.   return(critical);
  2410. }
  2411.  
  2412.  
  2413. /* Given direction "dir", returns new row, column location -RAK- */
  2414. int mmove(dir, y, x)
  2415. int dir;
  2416. register int *y, *x;
  2417. {
  2418.   register int new_row, new_col;
  2419.   int bool;
  2420.  
  2421.   switch(dir)
  2422.     {
  2423.     case 1:
  2424.       new_row = *y + 1;
  2425.       new_col = *x - 1;
  2426.       break;
  2427.     case 2:
  2428.       new_row = *y + 1;
  2429.       new_col = *x;
  2430.       break;
  2431.     case 3:
  2432.       new_row = *y + 1;
  2433.       new_col = *x + 1;
  2434.       break;
  2435.     case 4:
  2436.       new_row = *y;
  2437.       new_col = *x - 1;
  2438.       break;
  2439.     case 5:
  2440.       new_row = *y;
  2441.       new_col = *x;
  2442.       break;
  2443.     case 6:
  2444.       new_row = *y;
  2445.       new_col = *x + 1;
  2446.       break;
  2447.     case 7:
  2448.       new_row = *y - 1;
  2449.       new_col = *x - 1;
  2450.       break;
  2451.     case 8:
  2452.       new_row = *y - 1;
  2453.       new_col = *x;
  2454.       break;
  2455.     case 9:
  2456.       new_row = *y - 1;
  2457.       new_col = *x + 1;
  2458.       break;
  2459.     }
  2460.   bool = FALSE;
  2461.   if ((new_row >= 0) && (new_row < cur_height)
  2462.       && (new_col >= 0) && (new_col < cur_width))
  2463.     {
  2464.       *y = new_row;
  2465.       *x = new_col;
  2466.       bool = TRUE;
  2467.     }
  2468.   return(bool);
  2469. }
  2470.  
  2471. /* Saving throws for player character.        -RAK-    */
  2472. int player_saves()
  2473. {
  2474.   /* MPW C couldn't handle the expression, so split it into two parts */
  2475.   int16 temp = class_level_adj[py.misc.pclass][CLA_SAVE];
  2476.  
  2477.   if (randint(100) <= (py.misc.save + stat_adj(A_WIS)
  2478.                + (temp * py.misc.lev / 3)))
  2479.     return(TRUE);
  2480.   else
  2481.     return(FALSE);
  2482. }
  2483.  
  2484.  
  2485. /* Finds range of item in inventory list        -RAK-    */
  2486. int find_range(item1, item2, j, k)
  2487. int item1, item2;
  2488. register int *j, *k;
  2489. {
  2490.   register int i;
  2491.   register inven_type *i_ptr;
  2492.   int flag;
  2493.  
  2494.   i = 0;
  2495.   *j = -1;
  2496.   *k = -1;
  2497.   flag = FALSE;
  2498.   i_ptr = &inventory[0];
  2499.   while (i < inven_ctr)
  2500.     {
  2501.       if (!flag)
  2502.     {
  2503.       if ((i_ptr->tval == item1) || (i_ptr->tval == item2))
  2504.         {
  2505.           flag = TRUE;
  2506.           *j = i;
  2507.         }
  2508.     }
  2509.       else
  2510.     {
  2511.       if ((i_ptr->tval != item1) && (i_ptr->tval != item2))
  2512.         {
  2513.           *k = i - 1;
  2514.           break;
  2515.         }
  2516.     }
  2517.       i++;
  2518.       i_ptr++;
  2519.     }
  2520.   if (flag && (*k == -1))
  2521.     *k = inven_ctr - 1;
  2522.   return(flag);
  2523. }
  2524.  
  2525.  
  2526. /* Teleport the player to a new location        -RAK-    */
  2527. void teleport(dis)
  2528. int dis;
  2529. {
  2530.   register int y, x, i, j;
  2531.  
  2532.   do
  2533.     {
  2534.       y = randint(cur_height) - 1;
  2535.       x = randint(cur_width) - 1;
  2536.       while (distance(y, x, char_row, char_col) > dis)
  2537.     {
  2538.       y += ((char_row-y)/2);
  2539.       x += ((char_col-x)/2);
  2540.     }
  2541.     }
  2542.   while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (cave[y][x].cptr >= 2));
  2543.   move_rec(char_row, char_col, y, x);
  2544.   for (i = char_row-1; i <= char_row+1; i++)
  2545.     for (j = char_col-1; j <= char_col+1; j++)
  2546.       {
  2547.     cave[i][j].tl = FALSE;
  2548.     lite_spot(i, j);
  2549.       }
  2550.   lite_spot(char_row, char_col);
  2551.   char_row = y;
  2552.   char_col = x;
  2553.   check_view();
  2554.   creatures(FALSE);
  2555.   teleport_flag = FALSE;
  2556. }
  2557.